import React, { useEffect, useRef } from "react"
import Taro, { nextTick, useDidShow, useReady } from "@tarojs/taro"
import { pageMapperCommunity, tabbarPages } from "@/constants/pageMap"
import { syncTabbarActive } from "@/utils/tabbar"
import GpContainer from "@/components/GpContainer"
import { View, ScrollView, GridView, Image, StickySection } from "@tarojs/components"
import clsx from "clsx"
import { useLayout, useSetState } from "@/utils/hooks"
import { getChannelList, getChannelNotes } from "@/apis/yikao-community"
import TabbarPlaceholder from "../components/TabbarPlaceholder/index"
import GpNoteItem from "../../../note/components/GpNoteItem"
import styles from "./index.module.scss"
import { navigation } from "@/utils/router"
import { notePatchStack } from "@/constants/note"
import { isSkyline } from "@/utils/core"
import CustomTabbarForSkyline from "../components/CustomTabbarForSkyline"
import GpLoading from "@/components/GpLoading"
import { hasChosenInfo } from "@/utils/auth"
import GpEmpty from "@/components/GpEmpty"

type IState = {
  currentFilter: number
  channels: IOptionLike<number>[]
  currentChannel: number
  list: IApiRelative.IGetChannelNotes.INoteListItem[]
  current: number
  hasMore: boolean
  refresherTriggered: boolean
  /** 当前页面渲染后端是否是skyline */
  skyline: boolean
}

/**
 * @page 社区
 */
export default function Community() {
  const [layout] = useLayout()
  const filters = useRef<IOptionLike<number>[]>([
    { value: 0, label: "关注" },
    { value: 1, label: "推荐" }
  ])
  const [state, setState, stateRef] = useSetState<IState>(() => {
    return {
      currentFilter: filters.current[1].value,
      channels: [],
      currentChannel: 0,
      list: [],
      current: 1,
      hasMore: true,
      refresherTriggered: false,
      skyline: isSkyline()
    }
  }, true)
  const scrollCtx = useRef<any>()
  const triggerChosenInfoRef = useRef<boolean>(false)
  useEffect(() => {
    fetchChannelList().finally(() => {
      nextTick(shouldNavigateToChooseInfo)
    })
  }, [])
  useDidShow(() => {
    syncTabbarActive(tabbarPages.community)
    if (triggerChosenInfoRef.current) {
      triggerChosenInfoRef.current = false
      fetchChannelList()
    } else {
      patchNoteWhenBack()
    }
  })
  useReady(() => {
    getScrollContext()
  })
  function shouldNavigateToChooseInfo() {
    // 判断是否需要进入选择信息页面
    const { ignored, hasSet } = hasChosenInfo()
    if (ignored || hasSet) {
      // Do nothing
    } else {
      function navigate() {
        if (scrollCtx.current) {
          triggerChosenInfoRef.current = true
          navigation(pageMapperCommunity.ChooseInfo)
        } else {
          // 确保在拿到scrollview上下文后再进行跳转
          const t = setTimeout(() => {
            clearTimeout(t)
            navigate()
          }, 300)
        }
      }
      navigate()
    }
  }
  function getScrollContext() {
    Taro.createSelectorQuery()
      .select("#listScrollview")
      .node()
      .exec(res => {
        if (res && res[0]) {
          scrollCtx.current = res[0].node
          scrollCtx.current.enhanced = true
        } else {
          // IOS onReady有时获取不到node 重新获取知道获取成功即可
          getScrollContext()
        }
      })
  }
  /**
   * 从笔记详情点赞后退出 patch笔记点赞数和点赞状态
   * @reference https://www.tapd.cn/42905076/bugtrace/bugs/view?bug_id=1142905076001013186
   */
  function patchNoteWhenBack() {
    if (stateRef.current?.list && stateRef.current?.list.length > 0) {
      const patches = notePatchStack.get()
      if (patches.length > 0) {
        let matched = false
        const _list = stateRef.current.list.concat()
        for (const patch of patches) {
          const finder = _list.find(l => l.id === patch.id)
          if (finder) {
            finder.isSelfLike = patch.isSelfLike
            finder.likeCount = patch.likeCount
            if (!matched) {
              matched = true
            }
          }
        }
        if (matched) {
          setState({ list: _list })
        }
      }
    }
    notePatchStack.clear()
  }
  function handleScrollToLower() {
    if (stateRef.current?.hasMore) {
      setState({ current: stateRef.current.current + 1 })
      handleSearch()
    }
  }
  function fetchChannelList() {
    return getChannelList().then(res => {
      if (res.data && res.data.success) {
        const list = res.data.data.map<IOptionLike<number>>(l => {
          return {
            value: l.value,
            label: l.label
          }
        })
        list.unshift({
          value: -1,
          label: "精选"
        })
        setState({ channels: list, current: 1, hasMore: true })
        // 关注
        if (stateRef.current?.currentFilter === 0) {
          handleSearch()
        } else if (stateRef.current?.currentFilter === 1) {
          // 推荐
          let choosedChannel = list[0].value
          if (stateRef.current.currentChannel) {
            choosedChannel = stateRef.current.currentChannel
          }
          handleChannelChange(choosedChannel, true)
        }
      }
    })
  }
  function handleSearch() {
    if (!stateRef.current) return
    const search: IApiRelative.IGetChannelNotes.ISearch = {
      isFollowing: stateRef.current.currentFilter === 0
    }
    // 非关注
    if (stateRef.current.currentFilter !== 0 && stateRef.current.currentChannel !== -1) {
      search.channelId = stateRef.current.currentChannel
    }
    Taro.showLoading({ title: "加载中..." })
    getChannelNotes({
      pagination: {
        current: stateRef.current.current,
        pageSize: 20
      },
      sort: {
        predicate: "",
        reverse: false
      },
      search
    })
      .then(res => {
        if (res.data && res.data.success) {
          const { list, pagination } = res.data.data
          const newList =
            stateRef.current!.current === 1 ? list : [...stateRef.current!.list, ...list]
          setState({
            list: newList,
            hasMore: pagination.current < pagination.pageCount
          })
          if (stateRef.current!.current === 1) {
            if (scrollCtx.current) {
              scrollCtx.current.scrollTo({
                top: 0,
                animated: false
              })
            }
          }
        }
      })
      .finally(() => {
        Taro.hideLoading()
      })
  }
  function handleFilterChange(filter: number) {
    if (state.currentFilter === filter) return
    setState({ currentFilter: filter, current: 1, hasMore: true })
    handleSearch()
  }
  function handleChannelChange(channel: number, force = false) {
    if (state.currentChannel === channel && !force) return
    setState({ currentChannel: channel, current: 1, hasMore: true })
    handleSearch()
  }
  function renderNavigation() {
    return (
      <View className={styles.navigationBar}>
        <View
          style={{
            height: layout.statusBarHeight + "px"
          }}
        ></View>
        <View
          style={{
            height: layout.navigationHeight + "px"
          }}
          className={styles.navigation}
        >
          <Image
            src="https://csstatic.91goodschool.com/UpFiles/gp/1000/202404/15/141216356636.png"
            className={clsx(styles.searchIcon, "w-44px h-44px object-cover")}
            onClick={() => navigation(pageMapperCommunity.HomeSearch, { from: "community" })}
          />
          {filters.current.map((l, index) => (
            <View
              key={l.value}
              style={{
                lineHeight: layout.navigationHeight + "px",
                marginRight: index === 0 ? 18 : 0
              }}
              className={clsx(styles.filter, {
                [styles.filterActive]: state.currentFilter === l.value
              })}
              onClick={() => handleFilterChange(l.value)}
            >
              {l.label}
            </View>
          ))}
        </View>
      </View>
    )
  }
  function renderChannels() {
    return (
      <ScrollView scrollX className={styles.channels} enhanced>
        {state.channels.map(l => (
          <View
            key={l.value}
            className={clsx(styles.channel, {
              [styles.channelActive]: state.currentChannel === l.value
            })}
            onClick={() => handleChannelChange(l.value)}
          >
            {l.label}
          </View>
        ))}
      </ScrollView>
    )
  }
  function onLikeSuccess(
    noteItem: PrimaryKey<number>,
    meta: IApiRelative.INoteLikeSwitch.IResData
  ) {
    const _list = state.list.concat()
    const finder = _list.find(l => l.id === noteItem.id)
    if (finder) {
      finder.isSelfLike = meta.isLike
      finder.likeCount = meta.likeCount
      setState({ list: _list })
    }
  }
  function onRefresherRefresh() {
    setState({ refresherTriggered: true })
    fetchChannelList().finally(() => {
      setState({ refresherTriggered: false })
      if (scrollCtx.current) {
        scrollCtx.current.closeRefresh()
      }
    })
  }
  function renderLoading() {
    if (!state.hasMore) return null
    return (
      <View className="flex flex-row justify-center pt-32px pb-62px box-border">
        <GpLoading size={24} />
      </View>
    )
  }
  function renderList() {
    // 当切换到关注时 有16像素的间距
    const style: React.CSSProperties = {
      width: "100%",
      height: 0,
      boxSizing: "border-box"
    }
    if (state.currentFilter !== 1) {
      style.height = 16
    }
    return (
      <View
        className={clsx(styles.listWrapper, {
          "px-32px pb-96px": !state.skyline
        })}
      >
        <ScrollView
          padding={[0, 16, 48, 16]}
          type="custom"
          style={{
            height: "100%",
            boxSizing: "border-box"
          }}
          showScrollbar={false}
          scrollY
          id="listScrollview"
          enhanced
          onScrollToLower={handleScrollToLower}
          refresherEnabled
          refresherTriggered={state.refresherTriggered}
          onRefresherRefresh={onRefresherRefresh}
          refresherBackground="transparent"
        >
          <StickySection>
            <View style={style}></View>
          </StickySection>
          <StickySection>
            <GridView type="masonry" crossAxisCount={2} mainAxisGap={5} crossAxisGap={5}>
              {state.list.map((l, index) => (
                <GpNoteItem
                  skyline={state.skyline}
                  key={index}
                  noteItem={{
                    id: l.id,
                    actionFlag: false,
                    avatar: l.createdByHead,
                    image: l.thumbnail,
                    fileType: l.fileType,
                    liked: l.isSelfLike,
                    likes: l.likeCount,
                    name: l.createdByName,
                    title: l.title,
                    videoFlag: true,
                    content: l.description
                  }}
                  clickToNavigation
                  onLike={onLikeSuccess}
                />
              ))}
            </GridView>
            {renderLoading()}
          </StickySection>
        </ScrollView>
      </View>
    )
  }
  // function renderConcern() {
  //   return (
  //     <View className={styles.concerns}>
  //       <View className={styles.concern}>
  //         <View className={styles.concernTitle}>
  //           <Image src={mockSrc} className={styles.concernAvatar}/>
  //           <View className={styles.concernUser}>
  //             广州美术学院
  //           </View>
  //         </View>
  //         <View className={styles.cover}>
  //           <Image src={mockSrc} className={styles.coverImage}/>
  //         </View>
  //       </View>
  //     </View>
  //   )
  // }
  function renderConcernContent() {
    if (state.list.length > 0) {
      return renderList()
    } else {
      return (
        <GpEmpty
          imageProps={{
            src: "https://static.91goodschool.com/UpFiles/public/yikao/image/aixin.png",
            style: {
              width: 126,
              height: 112
            }
          }}
          emptyProps={{
            style: {
              paddingTop: 120
            }
          }}
          description="还没有关注的人哦"
        />
      )
    }
  }
  const varStyles = {
    "--navtop": layout.statusBarHeight + layout.navigationHeight + "px"
  }
  if (state.currentFilter !== 1) {
    varStyles["--filterheight"] = 0 + "px"
  }
  return (
    <GpContainer
      className="min-h-screen"
      pageGap={112}
      shareConfig={{
        title: "艺考交流社区"
      }}
    >
      <TabbarPlaceholder>
        {/* @ts-ignore */}
        <View className={clsx("bgBox bgBox2", styles.pageWrapper)} style={varStyles}>
          {renderNavigation()}
          {state.currentFilter === 1 ? renderChannels() : null}
          {state.currentFilter === 1 ? renderList() : renderConcernContent()}
        </View>
        {/* 由于当前taro框架原因, 在skyline渲染模式下自定义tabbar不生效, 所以此处显示加上自定义tabbar组件 */}
        {state.skyline && <CustomTabbarForSkyline />}
      </TabbarPlaceholder>
    </GpContainer>
  )
}
